package ch.evaleto.gwt.media.client.player;

import java.util.ArrayList;
import java.util.List;

import ch.evaleto.gwt.media.client.player.util.EventListener;
import ch.evaleto.gwt.media.client.player.util.EventListenerList;

public class Queue {
	private final List<Media> medias=new ArrayList<Media>();
	private EventListenerList listeners;
	
	private static Queue root;
	private boolean loop;
	private int current;
	
	public Queue() {
		final Queue me=this;
		listeners=new EventListenerList(){
			public void callEvent(String name, EventListener event, Object sender) {
				me.callEvent(name, event,sender);
			}
		};
		PlayerManager.get().addPlayerListener(new PlayerListener(){
			//media is done
			public void onFinish() {
				next();
			}
			// player is ready
			public void onInstance(Player player) {
			}
			//update the display
			public void onPlaying(Media media) {
			}
			
		});
		current=0;
		loop=true;
	}
	protected void callEvent(String name, EventListener event, Object sender) {
		QueueListener e=(QueueListener)event;
	}
	
	public boolean isEmpty(){
		return medias.size()==0;
	}
	
	public void pause() {
		PlayerManager.get().pause(current());
	}

	public void play() {
		PlayerManager.get().play(current());
		
	}

	public void resume() {
		PlayerManager.get().resume(current());
	}

	public void stop() {
		PlayerManager.get().stop(current());
	}

	public void toggle() {
		PlayerManager.get().toggle(current());
	}
	
	public void add(Playlist list){
		medias.addAll(list.medias);
	}
	
	public void add(Media media){
		medias.add(media);
		listeners.call("onadd",media);
	}
	
	public void remove(Media media){
		listeners.call("onremove",media);
		medias.remove(media);	
	}

	public void remove(int media){
		listeners.call("onremove",medias.get(media));
		medias.remove(media);	
	}
	
	public void removeAll(){
		medias.clear();	
	}
	
	public Media current(){
		listeners.call("oncurrent",medias.get(current));
		return medias.get(current);
	}
	
	public Media next(){
		Media c;
		if (!loop)
			medias.remove(current);
		stop();
		if (current>=medias.size())
			if (loop)
				current=0;
			else
				return Media.Null;
		else current++;
		play();
		return current();
	}
	public Media back(){
		stop();
		if (current==0)
			if (loop)
				current=medias.size()-1;
			else
				return Media.Null;
		else current--;
		play();
		return medias.get(current);
	}
	
	public Media random(){
		stop();
		if (!loop)
			medias.remove(current);
		// its not a true random if it can play two times the same...
		current=(int)Math.round((Math.random()*current));
		play();
		return current();
	}
	
	public void setLoop(boolean loop){
		this.loop=loop;
	}
	
	
	public static Queue getRoot(){
		if (root==null)
			root=new Queue();
		return root;
	}
}
